home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / asmsrc / thesource-7.lha / Source / DefFunc.lha / DefFunc / defunc.c < prev    next >
C/C++ Source or Header  |  1993-12-14  |  14KB  |  497 lines

  1. /*********************************************************
  2.  *
  3.  *    Copyright (c) 1993  Ke Jin 
  4.  *
  5.  *    Permission to use, copy, modify, and distribute 
  6.  *    this software and its documentation without fee
  7.  *    is granted, provided that the author's name and
  8.  *    this copyright notice are retained.
  9.  * 
  10.  * -----------------------------------------------------
  11.  *
  12.  *    defunc.c -- defunc high level module 
  13.  *
  14.  *    public  function : dfopen();
  15.  *                       dfclose();
  16.  *                       dfcloseall();
  17.  *
  18.  *    private function : getfreehdl();
  19.  *                       tdfopen();
  20.  *                       getexprbody();
  21.  *                       getexprname();
  22.  *                       getexprset();
  23.  *                       isfnctexpr();
  24.  *
  25.  *                       brkbalance();
  26.  *
  27.  *                       hdl00() to hdl31();
  28.  *
  29.  *    private variable : tr_arr[];
  30.  *                     : hdl_arr[];
  31.  *
  32.  *********************************************************/
  33.  
  34. #include <stdio.h>
  35. #include <malloc.h>
  36. #include <ctype.h> 
  37. #include <string.h>
  38.  
  39. #include "dfctree.h"
  40. #include "dfcsymtable.h"
  41. #include "defunc.h"
  42.  
  43. #ifdef __cplusplus   /* for c++ */
  44.   extern "C" {
  45. #endif
  46.  
  47. #define MAXHANDLE 32
  48.  
  49. typedef Node* Tree;
  50. typedef double (*FP)();
  51.  
  52. #if NeedFunctionPrototypes
  53.   static Tree   tr_arr[MAXHANDLE];  /* predeclare static member */
  54.   static FP     hdl_arr[MAXHANDLE]; /* predeclare static member */
  55.   static char*  getexprbody(char* inputstr);
  56.   static char*  getexprname(char* inputstr);
  57.   static char*  getarguset(char* inputstr, int argidx);
  58.   static int    isfnctexpr(char* inputstr);
  59.   static int    brkbalance(char* inputstr);
  60. #else
  61.   extern Tree   tr_arr[MAXHANDLE];  /* predeclare static member */
  62.   extern FP     hdl_arr[MAXHANDLE]; /* predeclare static member */
  63.   extern char*  getexprbody();
  64.   extern char*  getexprname();
  65.   extern char*  getarguset();
  66.   extern int    isfnctexpr();
  67.   extern int    brkbalance();
  68. #endif /* predeclare private function */
  69.  
  70. #if NeedFunctionPrototypes
  71.   static int getfreehdl(void)
  72. #else
  73.   static int getfreehdl() 
  74. #endif
  75. /* return the index of free handle on success. return -1 on fail */
  76. {
  77.     int i;
  78.  
  79.     for(i=0;i<MAXHANDLE;i++)
  80.     {
  81.     if(tr_arr[i]==(Node*)0) return i;
  82.     }
  83.  
  84.     return -1;    /* if no free handle */
  85. };
  86.  
  87. #if NeedFunctionPrototypes
  88.   static double (*tdfopen(char* exprbody))(double x, double y)
  89. #else
  90.   static double (*tdfopen(exprbody))() 
  91.   char* exprbody;
  92. #endif
  93. /* Only accept expression body. Return handle function or NULL */
  94. {
  95.     int i, size;
  96.  
  97.     if(brkbalance(exprbody)!=0)  
  98.     {
  99.         exparserror = "unbalanced ( ) in expression";
  100.     return 0;
  101.     }
  102.  
  103.     if((i=getfreehdl())==-1)  return 0; /* no free handle */
  104.     
  105.     size = exparse(exprbody);
  106.     if(size<=0) return 0;
  107.  
  108.     tr_arr[i] = (Node*)malloc(sizeof(Node)*size); 
  109.     if(tr_arr[i]==0) 
  110.     {
  111.     exparserror = "fail to alloc memory for new parse tree";
  112.     return 0;
  113.     }
  114.  
  115.     getparsetree(tr_arr[i]);
  116.     reduce(tr_arr[i], 0);
  117.  
  118.     return hdl_arr[i];
  119. };
  120.  
  121. #if NeedFunctionPrototypes
  122.   double (*dfopen(char* expr))(double x, double y)
  123. #else
  124.   double (*dfopen(expr))()
  125.   char* expr;
  126. #endif 
  127. /* Accept full expression as well as expression 
  128.  * body.  Return handle function or NULL */
  129. {
  130.     double (*fnctptr)();
  131.  
  132.     char* exprbody;
  133.     char* exprname;
  134.     char  *arg1, *arg2;
  135.  
  136.     exparserror = 0;
  137.     if(brkbalance(expr)!=0)
  138.     {
  139.     exparserror = "unbalanced ( ) in expression";
  140.     return 0;
  141.     }
  142.  
  143.     exprbody = getexprbody(expr);
  144.     exprname = getexprname(expr);
  145.     arg1     = getarguset(expr, 1);
  146.     arg2     = getarguset(expr, 2);
  147.  
  148.     if(nameargu(arg1, arg2)==-1)
  149.     {
  150.     exparserror = "error on reset argument";
  151.     return 0;
  152.     }
  153.  
  154.     fnctptr = tdfopen(exprbody);
  155.  
  156.     if(exprname!=0)
  157.     {
  158.     if(arg1!=0||isfnctexpr(expr)) 
  159.     {
  160.         namefnct(exprname, fnctptr);
  161.         }
  162.     else if(fnctptr!=0)
  163.     {
  164.         namecnst(exprname, fnctptr());
  165.         }
  166.     }
  167.  
  168.     return fnctptr;
  169. };
  170.  
  171. #if NeedFunctionPrototypes
  172.   int dfclose(double (*fnctptr)())
  173. #else
  174.   int dfclose(fnctptr)
  175.   double (*fnctptr)();
  176. #endif
  177. /* close a dynamic function(getten from dfopen) if it not on
  178.  * the global name-function association table. On success,
  179.  * return 0. On fail return -1 
  180.  */
  181. {
  182.     int i;
  183.     if(getsym(getfnctname(fnctptr))!=0) return -1; 
  184.     /* function still on symbol table can't be closed */ 
  185.  
  186.     for(i=0;i<MAXHANDLE;i++)
  187.     {
  188.     if(fnctptr==hdl_arr[i])
  189.     {
  190.         if(tr_arr[i]!=0) free(tr_arr[i]);
  191.         tr_arr[i]=0;
  192.         return 0; /* success */
  193.         }
  194.     }
  195.  
  196.     return -1; /* fail to close */
  197. };
  198.  
  199. #if NeedFunctionPrototypes
  200.   int dfcloseall(void)
  201. #else
  202.   int dfcloseall()
  203. #endif
  204. /* close all (not on the association table) dynamic functions  
  205.  * Return the total number of handler freed by this calling.
  206.  */
  207. {
  208.      int i, j;
  209.  
  210.      for(i=0, j=0; i<MAXHANDLE; i++)
  211.      {
  212.      if(tr_arr[i]!=0)  /* unfreed handle */ 
  213.      {
  214.          if(dfclose(hdl_arr[i])==0) /* success */
  215.          {
  216.            tr_arr[i]=0;
  217.            j++;
  218.              }
  219.          }
  220.      }
  221.  
  222.      return j;
  223. };
  224.  
  225. #if NeedFunctionPrototypes
  226.    static char* getexprbody(char* str)
  227. #else 
  228.    static char* getexprbody(str)
  229.    char* str;
  230. #endif
  231. /* extract the expression body from an input string */
  232. {
  233.     int i;
  234.  
  235.     for(i=0;i<strlen(str);i++)
  236.     {
  237.         if(str[i]=='=') return str+i+1;
  238.     /* found '=' in str, substring after '=' be returned */
  239.  
  240.     }
  241.  
  242.     return str; /* no '=' be found, then return str itself */
  243. };
  244.  
  245. #if NeedFunctionPrototypes
  246.    static char* getexprname(char* str)
  247. #else
  248.    static char* getexprname(str)
  249.    char* str;
  250. #endif
  251. /* extract the expression title from an input string */
  252. {
  253.     int i, j=0, len;
  254.     static char* name;
  255.  
  256.     for(i=0; i<strlen(str);i++)
  257.     {
  258.     if(str[i]=='=') break;
  259.     /* if no '=' be found, then it's a anonymous expression */
  260.     }
  261.     if(i==strlen(str)) return 0;
  262.  
  263.     len = i;
  264.  
  265.     name = (char*)malloc(len*sizeof(char));
  266.     if(name == 0) 
  267.     {
  268.     perror("malloc in getarguset()");
  269.     exit(1);
  270.     }
  271.  
  272.     for(i=0; i<len; i++)
  273.     {
  274.         if(isalnum(str[i])) 
  275.     {
  276.         name[j] = str[i];
  277.         j++;
  278.         }
  279.     else break;
  280.     }
  281.  
  282.     name[j]= '\0';
  283.     if(strlen(name)==0) return 0;
  284.     return name;
  285. };
  286.  
  287. #if NeedFunctionPrototypes
  288.     static char* getarguset(char* str, int argidx)
  289. #else
  290.     static char* getarguset(str, argidx)
  291.     char* str;
  292.     int   argidx;
  293. #endif
  294. /* extract an argument name from input string */
  295. {
  296.     int i, j=0, len;
  297.     char   c;
  298.     static char *name1;
  299.     static char *name2;
  300.  
  301.     for(i=0; i<strlen(str); i++)
  302.     {
  303.     if(str[i]=='=') break;
  304.     /* if no '=' be found, then it's a anonymous expression */
  305.     }
  306.     if(i==strlen(str)) return 0;
  307.     len=i; 
  308.     /* len is the length of substring (those part in front of '=') */
  309.  
  310.     for(i=0; i<len; i++)
  311.     {
  312.     if(argidx==1)  
  313.         {
  314.         name1 = (char*)malloc(len*sizeof(char));
  315.         if(name1 == 0)
  316.         {
  317.             perror("malloc in getarguset()");
  318.                 exit(1);
  319.             }
  320.  
  321.         if(str[i] == '(')     /* skim over the expr name */
  322.         {
  323.             for(i=i+1;i<len;i++)
  324.             {
  325.             c = str[i];
  326.             if(j==0&&(c==' '||c=='\t')) continue;
  327.                 if(c!=','&&c!=')'&&c!='='&&c!=' '&&c!='\t') 
  328.             { 
  329.                 name1[j]=c;
  330.                 j++;
  331.                     }
  332.             else break;
  333.                 }
  334.         name1[j]='\0';
  335.         if(strlen(name1)==0) return 0;
  336.         return name1; 
  337.             }
  338.         }
  339.  
  340.     if(argidx==2)
  341.     {
  342.         name2 = (char*)malloc(len*sizeof(char));
  343.         if(name2 == 0)
  344.             {
  345.             perror("malloc in getarguset()");
  346.         exit(1);
  347.             }    
  348.  
  349.         if(str[i] == ',')     
  350.               /* skim over the expr and 1st argu names */
  351.             {
  352.         for(i=i+1;i<len;i++)
  353.         {
  354.             c=str[i];
  355.             if(j==0&&(c==' '||c=='\t')) continue;
  356.             if(c!=','&&c!=')'&&c!='='&&c!=' '&&c!='\t')
  357.             {
  358.             name2[j]=str[i];
  359.             j++;
  360.                     }
  361.             else break; 
  362.                 }
  363.         name2[j]='\0';
  364.         if(strlen(name2)==0) return 0;
  365.         return name2;
  366.             }
  367.         }
  368.     }
  369.  
  370.     return 0;
  371. };
  372.  
  373. #if NeedFunctionPrototypes
  374.   static int isfnctexpr(char* expression)
  375. #else
  376.   static int isfnctexpr(expression)
  377.   char* expression;
  378. #endif
  379. /* to see the title is in "name(...)=" form or in "name=" form */
  380. {
  381.     int i, tag=0;
  382.     char c;
  383.  
  384.     if(expression==0) return 0;
  385.  
  386.     for(i=0; i<strlen(expression); i++)
  387.     {
  388.     c=expression[i];
  389.     if(c=='(') tag=1;
  390.     if(c=='=') return tag;
  391.     }
  392.  
  393.     return tag;
  394. };
  395.  
  396. #if NeedFunctionPrototypes
  397.   static int brkbalance(char* expression) 
  398. #else
  399.   static int brkbalance(expression)
  400.   char* expression;
  401. #endif
  402. /* check the balance of '(' and ')'. Return 0 on balance */
  403. {
  404.     int  i,j;
  405.     char c;
  406.  
  407.     for(i=0, j=0;i<strlen(expression);i++)
  408.     {
  409.     c = expression[i];
  410.     if(c=='(') j++;
  411.     if(c==')') j--;
  412.     }
  413.  
  414.     return j;
  415. };
  416.         
  417. /* ------------------------- private members  ------------------------ */
  418. static  Tree   tr_arr[MAXHANDLE];
  419.  
  420. #if NeedFunctionPrototypes
  421.  static double hdl00(double x,double y){return evaluate(tr_arr[ 0],0,x,y);};
  422.  static double hdl01(double x,double y){return evaluate(tr_arr[ 1],0,x,y);};
  423.  static double hdl02(double x,double y){return evaluate(tr_arr[ 2],0,x,y);};
  424.  static double hdl03(double x,double y){return evaluate(tr_arr[ 3],0,x,y);};
  425.  static double hdl04(double x,double y){return evaluate(tr_arr[ 4],0,x,y);};
  426.  static double hdl05(double x,double y){return evaluate(tr_arr[ 5],0,x,y);};
  427.  static double hdl06(double x,double y){return evaluate(tr_arr[ 6],0,x,y);};
  428.  static double hdl07(double x,double y){return evaluate(tr_arr[ 7],0,x,y);};
  429.  static double hdl08(double x,double y){return evaluate(tr_arr[ 8],0,x,y);};
  430.  static double hdl09(double x,double y){return evaluate(tr_arr[ 9],0,x,y);};
  431.  static double hdl10(double x,double y){return evaluate(tr_arr[10],0,x,y);};
  432.  static double hdl11(double x,double y){return evaluate(tr_arr[11],0,x,y);};
  433.  static double hdl12(double x,double y){return evaluate(tr_arr[12],0,x,y);};
  434.  static double hdl13(double x,double y){return evaluate(tr_arr[13],0,x,y);};
  435.  static double hdl14(double x,double y){return evaluate(tr_arr[14],0,x,y);};
  436.  static double hdl15(double x,double y){return evaluate(tr_arr[15],0,x,y);};
  437.  static double hdl16(double x,double y){return evaluate(tr_arr[16],0,x,y);};
  438.  static double hdl17(double x,double y){return evaluate(tr_arr[17],0,x,y);};
  439.  static double hdl18(double x,double y){return evaluate(tr_arr[18],0,x,y);};
  440.  static double hdl19(double x,double y){return evaluate(tr_arr[19],0,x,y);};
  441.  static double hdl20(double x,double y){return evaluate(tr_arr[20],0,x,y);};
  442.  static double hdl21(double x,double y){return evaluate(tr_arr[21],0,x,y);};
  443.  static double hdl22(double x,double y){return evaluate(tr_arr[22],0,x,y);};
  444.  static double hdl23(double x,double y){return evaluate(tr_arr[23],0,x,y);};
  445.  static double hdl24(double x,double y){return evaluate(tr_arr[24],0,x,y);};
  446.  static double hdl25(double x,double y){return evaluate(tr_arr[25],0,x,y);};
  447.  static double hdl26(double x,double y){return evaluate(tr_arr[26],0,x,y);};
  448.  static double hdl27(double x,double y){return evaluate(tr_arr[27],0,x,y);};
  449.  static double hdl28(double x,double y){return evaluate(tr_arr[28],0,x,y);};
  450.  static double hdl29(double x,double y){return evaluate(tr_arr[29],0,x,y);};
  451.  static double hdl30(double x,double y){return evaluate(tr_arr[30],0,x,y);};
  452.  static double hdl31(double x,double y){return evaluate(tr_arr[31],0,x,y);};
  453. #else
  454.  static double hdl00(x,y) double x,y; {return evaluate(tr_arr[ 0],0,x,y);};
  455.  static double hdl01(x,y) double x,y; {return evaluate(tr_arr[ 1],0,x,y);};
  456.  static double hdl02(x,y) double x,y; {return evaluate(tr_arr[ 2],0,x,y);};
  457.  static double hdl03(x,y) double x,y; {return evaluate(tr_arr[ 3],0,x,y);};
  458.  static double hdl04(x,y) double x,y; {return evaluate(tr_arr[ 4],0,x,y);};
  459.  static double hdl05(x,y) double x,y; {return evaluate(tr_arr[ 5],0,x,y);};
  460.  static double hdl06(x,y) double x,y; {return evaluate(tr_arr[ 6],0,x,y);};
  461.  static double hdl07(x,y) double x,y; {return evaluate(tr_arr[ 7],0,x,y);};
  462.  static double hdl08(x,y) double x,y; {return evaluate(tr_arr[ 8],0,x,y);};
  463.  static double hdl09(x,y) double x,y; {return evaluate(tr_arr[ 9],0,x,y);};
  464.  static double hdl10(x,y) double x,y; {return evaluate(tr_arr[10],0,x,y);};
  465.  static double hdl11(x,y) double x,y; {return evaluate(tr_arr[11],0,x,y);};
  466.  static double hdl12(x,y) double x,y; {return evaluate(tr_arr[12],0,x,y);};
  467.  static double hdl13(x,y) double x,y; {return evaluate(tr_arr[13],0,x,y);};
  468.  static double hdl14(x,y) double x,y; {return evaluate(tr_arr[14],0,x,y);};
  469.  static double hdl15(x,y) double x,y; {return evaluate(tr_arr[15],0,x,y);};
  470.  static double hdl16(x,y) double x,y; {return evaluate(tr_arr[16],0,x,y);};
  471.  static double hdl17(x,y) double x,y; {return evaluate(tr_arr[17],0,x,y);};
  472.  static double hdl18(x,y) double x,y; {return evaluate(tr_arr[18],0,x,y);};
  473.  static double hdl19(x,y) double x,y; {return evaluate(tr_arr[19],0,x,y);};
  474.  static double hdl20(x,y) double x,y; {return evaluate(tr_arr[20],0,x,y);};
  475.  static double hdl21(x,y) double x,y; {return evaluate(tr_arr[21],0,x,y);};
  476.  static double hdl22(x,y) double x,y; {return evaluate(tr_arr[22],0,x,y);};
  477.  static double hdl23(x,y) double x,y; {return evaluate(tr_arr[23],0,x,y);};
  478.  static double hdl24(x,y) double x,y; {return evaluate(tr_arr[24],0,x,y);};
  479.  static double hdl25(x,y) double x,y; {return evaluate(tr_arr[25],0,x,y);};
  480.  static double hdl26(x,y) double x,y; {return evaluate(tr_arr[26],0,x,y);};
  481.  static double hdl27(x,y) double x,y; {return evaluate(tr_arr[27],0,x,y);};
  482.  static double hdl28(x,y) double x,y; {return evaluate(tr_arr[28],0,x,y);};
  483.  static double hdl29(x,y) double x,y; {return evaluate(tr_arr[29],0,x,y);};
  484.  static double hdl30(x,y) double x,y; {return evaluate(tr_arr[30],0,x,y);};
  485.  static double hdl31(x,y) double x,y; {return evaluate(tr_arr[31],0,x,y);}; 
  486. #endif
  487.  
  488. static FP     hdl_arr[MAXHANDLE] ={ 
  489.               hdl00, hdl01, hdl02, hdl03, hdl04, hdl05, hdl06, hdl07, 
  490.               hdl08, hdl09, hdl10, hdl11, hdl12, hdl13, hdl14, hdl15, 
  491.               hdl16, hdl17, hdl18, hdl19, hdl20, hdl21, hdl22, hdl23,
  492.               hdl24, hdl25, hdl26, hdl27, hdl28, hdl29, hdl30, hdl31 };
  493.  
  494. #ifdef __cplusplus
  495.   }        /* end for c++ */
  496. #endif
  497.